BrocastReceiver是個廣播接收元件,當系統發生一些事情如連接網路、開始充電、重新開機時,BroadcastRecaiver會有所反應並讓我們做相應的處理。
BroadcastReceiver可以在Activity內運作也可以獨立運作,例如當使用者在Activity中時我想知道現在有無網路,就為此Activity註冊一個BroadcatReceiver來接收網路連線事件。若是系統相關的例如裝置重新開機,此時畫面必定不是在我們的Activity上,就可以為整個APP註冊一個獨立的BroadcastReceiver來監聽。
我們為Activity註冊一個BroadcastReceiver,接收使用者開啟或關閉網路的事件
在AndroidManifest.xml中加入權限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Java程式碼
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onResume()
{
super.onResume();
// 註冊mConnReceiver,並用IntentFilter設置接收的事件類型為網路開關
this.registerReceiver(mConnReceiver,
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
@Override
public void onPause()
{
super.onPause();
// 解除註冊
this.unregisterReceiver(mConnReceiver);
}
// 建立一個BroadcastReceiver,名為mConnReceiver
private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 當使用者開啟或關閉網路時會進入這邊
// 判斷目前有無網路
if(isNetworkAvailable()) {
// 以連線至網路,做更新資料等事情
Toast.makeText(MainActivity.this, "有網路!", Toast.LENGTH_SHORT).show();
}
else {
// 沒有網路
Toast.makeText(MainActivity.this, "沒網路!", Toast.LENGTH_SHORT).show();
}
}
};
// 回傳目前是否已連線至網路
public boolean isNetworkAvailable()
{
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
return networkInfo != null &&
networkInfo.isConnected();
}
}
在onResume中註冊並在onStop解除註冊,因為當使用者離開頁面時我們不用再判斷是否有網路,等他返回時再開始判斷就好。
註冊時的IntentFilter就是指定我們的BroadcastReceiver要接收哪種事件,使用CONNECTIVITY_ACTION接收使用者開關網路事件,這樣當每次開關網路時就會進入onReceive中,我們再判斷是否有網路並做處理。
開關網路事件並不限於Wifi或行動網路,不管開或關哪個都會執行onReceive,若想進一步判斷目前連線是否為Wifi就將isNetworkAvailable的回傳改成
return networkInfo != null &&
networkInfo.isConnected() &&
networkInfo.getType() == ConnectivityManager.TYPE_WIFI;
執行APP,開關網路時就會顯示訊息囉
建立一個獨立運作的BroadcastReceiver跟建立Activity的方式雷同,先建一個新的Java class,內容如下
public class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// 接收到事件時要做的事,要接收哪種事件則寫在AndroidManifest裡
}
}
在AndroidManifest.xml中加入BroadcastReceiver,用intent-filter設定要接收的事件,此處接收AIRPLANE_MODE所以會在開或關飛航模式時進入onReceive
<receiver
android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.AIRPLANE_MODE" />
</intent-filter>
</receiver>
這樣就完成囉
Android 7.0開始因為系統省電考量,獨立的BroadcastReceiver無法接收CONNECTIVITY_CHANGE(網路開關)事件,若有這個需求的話須改用JobScheduler等方式完成,可以參考Android Developers說明進一步了解。